import {
  Controller,
  Post,
  UseInterceptors,
  UploadedFile,
  UploadedFiles,
  Get,
  Param,
  Res,
  Delete,
  BadRequestException,
  Header,
} from '@nestjs/common';
import { FileInterceptor, FilesInterceptor } from '@nestjs/platform-express';
import { UploadService } from './upload.service';
import type { Express } from 'express';
import { exec } from 'child_process';
import type { Response } from 'express';
import * as path from 'path';
import * as fs from 'fs';
import { existsSync } from 'fs';
import { join } from 'path';
import { multerConfig } from '../config/multer.config';
@Controller('upload')
export class UploadController {
  constructor(private readonly uploadService: UploadService) {}
  @Post('upload')
  @UseInterceptors(FileInterceptor('file', multerConfig))
  async uploadFile2(@UploadedFile() file: Express.Multer.File) {
    const fileInfo = await this.uploadService.saveFile2(file);

    return {
      code: 200,
      message: '文件上传成功',
      data: fileInfo,
    };
  }

  @Post()
  @UseInterceptors(FileInterceptor('file', multerConfig))
  async uploadFile(@UploadedFile() file: Express.Multer.File) {
    const fileInfo = await this.uploadService.saveFile2(file);
    const uploadDir = path.join(
      __dirname,
      '..',
      '..',
      'uploads',
      fileInfo.filename,
    );
    console.log(uploadDir);

    let sqlPath = await parseBinlogWithMysqlbinlog(uploadDir);
    console.log(sqlPath);

    return {
      message: 'Binlog 解析完成，SQL 文件已生成。',
      pathName: sqlPath,
    };
  }
  @Get('download/:filename')
  @Header('Content-Type', 'application/octet-stream')
  async downloadFile(
    @Param('filename') filename: string,
    @Res() res: Response,
  ) {
    const filePath = this.uploadService.getFilePhysicalPath(filename);

    if (!existsSync(filePath)) {
      throw new BadRequestException('文件不存在');
    }

    // 设置下载头信息
    res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
    res.sendFile(filePath);
  }
}

async function parseBinlogWithMysqlbinlog(filePath: string): Promise<string> {
  return new Promise((resolve, reject) => {
    const outputDir = path.join(__dirname, '..', '..', 'uploads');
    if (!fs.existsSync(outputDir)) {
      fs.mkdirSync(outputDir);
    }
    let numberDate = new Date().getTime();
    const sqlFilePath = path.join(outputDir, `${numberDate}.sql`);

    const command = `mysqlbinlog --base64-output=DECODE-ROWS -v "${filePath}" > "${sqlFilePath}"`;

    exec(command, (error, stdout, stderr) => {
      if (error) {
        reject(error);
        return;
      }
      if (stderr) {
        console.error(`Stderr: ${stderr}`);
      }
      resolve(`${numberDate}.sql`);
    });
  });
}
